﻿Imports System.Web.Script.Serialization

Public Class JSONObject
    Const NEGATIVE_ZERO = -0D
    Dim nameValuePairs As Dictionary(Of String, Object)
    Public Sub New()
        nameValuePairs = New Dictionary(Of String, Object)
    End Sub
    Public Sub New(ByVal d As Dictionary(Of String, Object))
        nameValuePairs = d
    End Sub
    Public Sub New(ByVal sd As SortedDictionary(Of String, Object))
        nameValuePairs = New Dictionary(Of String, Object)
        For Each kvp As KeyValuePair(Of String, Object) In sd   '遍历元素
            nameValuePairs.Add(kvp.Key, kvp.Value)
        Next
    End Sub
    Public Sub New(ByVal sl As SortedList(Of String, Object))
        nameValuePairs = New Dictionary(Of String, Object)
        For Each kvp As KeyValuePair(Of String, Object) In sl   '遍历元素
            nameValuePairs.Add(kvp.Key, kvp.Value)
        Next
    End Sub
    Public Sub New(ByVal hash As Hashtable)
        nameValuePairs = New Dictionary(Of String, Object)
        For Each de As DictionaryEntry In hash
            nameValuePairs.Add(de.Key, de.Value)
        Next
    End Sub
    Public Sub New(ByVal o As Object)
        If o.GetType.Equals(GetType(Dictionary(Of String, Object))) Then
            nameValuePairs = o
        ElseIf o.GetType.Equals(GetType(SortedDictionary(Of String, Object))) Then
            Dim sd As SortedDictionary(Of String, Object) = o
            nameValuePairs = New Dictionary(Of String, Object)
            For Each kvp As KeyValuePair(Of String, Object) In sd   '遍历元素
                nameValuePairs.Add(kvp.Key, kvp.Value)
            Next
        ElseIf o.GetType.Equals(GetType(SortedList(Of String, Object))) Then
            Dim sl As SortedList(Of String, Object) = o
            For Each kvp As KeyValuePair(Of String, Object) In sl   '遍历元素
                nameValuePairs.Add(kvp.Key, kvp.Value)
            Next
        ElseIf o.GetType.Equals(GetType(Hashtable)) Then
            Dim hash As Hashtable = o
            nameValuePairs = New Dictionary(Of String, Object)
            For Each de As DictionaryEntry In hash
                nameValuePairs.Add(de.Key, de.Value)
            Next
        End If
    End Sub
    ''' <summary>
    ''' 使用标记器中下一个对象的名称/值映射创建一个新的<code>JSONTokener</code>。
    ''' </summary>
    ''' <param name="readFrom"></param>
    ''' <remarks></remarks>
    Public Sub New(ByVal readFrom As JSONTokener)
        Dim obj As Object = readFrom.NextValue()
        If obj.GetType.Equals(GetType(JSONObject)) Then
            nameValuePairs = obj
        Else
            Throw JSON.typeMismatch(obj, "JSONObject")
        End If
    End Sub
    ''' <summary>
    ''' 使用JSON字符串中的名称/值映射创建一个新的<code>JSONTokener</code>。
    ''' </summary>
    ''' <param name="js"></param>
    ''' <remarks></remarks>
    Public Sub New(ByVal js As String)
        Try
            Dim readFrom As JSONTokener = New JSONTokener(js)
            Dim obj As Object = readFrom.NextValue()
            If obj.GetType.Equals(GetType(JSONObject)) Then
                nameValuePairs = obj
            Else
                Throw JSON.typeMismatch(obj, "JSONObject")
            End If
        Catch ex As Exception
            nameValuePairs = New JavaScriptSerializer().DeserializeObject(js)
        End Try
    End Sub
    ''' <summary>
    ''' 通过从给定对象复制列出的名称的映射，创建一个新的<code>JSONObject</code>。将跳过<code>copyFrom</code>中不存在的名称。
    ''' </summary>
    ''' <param name="copyFrom">要复制的JSONObject对象</param>
    ''' <param name="names">新的名称</param>
    ''' <remarks></remarks>
    Public Sub New(ByVal copyFrom As JSONObject, ByVal names() As String)
        Me.New()
        For Each name As String In names
            Dim val As Object = copyFrom.opt(name)
            If Not Microsoft.VisualBasic.IsNothing(val) Then
                nameValuePairs.Add(name, val)
            End If
        Next
    End Sub
    ' ''' <summary>
    ' ''' 返回此对象中名称/值映射的数目。
    ' ''' </summary>
    ' ''' <returns></returns>
    ' ''' <remarks></remarks>
    'Public Function length() As Integer
    '    Return nameValuePairs.Count()
    'End Function

    ''' <summary>
    ''' 将指定值与此映射中的指定键相关联。如果映射以前包含键的映射，则替换旧值。
    ''' </summary>
    ''' <param name="name">与指定值关联的键</param>
    ''' <param name="value">要与指定键关联的值</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function put(ByVal name As String, ByVal value As Boolean) As JSONObject
        If checkName(name) Then
            If nameValuePairs.ContainsKey(name) Then
                nameValuePairs.Item(name) = value
                'Me.Item(name) = value
            Else
                nameValuePairs.Add(name, value)
                ' Me.Add(name, value)
            End If
            Return Me
        Else
            Return Me
        End If
    End Function
    ''' <summary>
    ''' 将指定值与此映射中的指定键相关联。如果映射以前包含键的映射，则替换旧值。
    ''' </summary>
    ''' <param name="name">与指定值关联的键</param>
    ''' <param name="value">要与指定键关联的值</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function put(ByVal name As String, ByVal value As Byte) As JSONObject
        If checkName(name) Then
            If nameValuePairs.ContainsKey(name) Then
                nameValuePairs.Item(name) = value
                ' Me.Item(name) = value
            Else
                nameValuePairs.Add(name, value)
                'Me.Add(name, value)
            End If
            Return Me
        Else
            Return Me
        End If
    End Function
    ''' <summary>
    ''' 将指定值与此映射中的指定键相关联。如果映射以前包含键的映射，则替换旧值。
    ''' </summary>
    ''' <param name="name">与指定值关联的键</param>
    ''' <param name="value">要与指定键关联的值</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function put(ByVal name As String, ByVal value As Char) As JSONObject
        If checkName(name) Then
            If nameValuePairs.ContainsKey(name) Then
                nameValuePairs.Item(name) = value
                'Me.Item(name) = value
            Else
                nameValuePairs.Add(name, value)
                ' Me.Add(name, value)
            End If
            Return Me
        Else
            Return Me
        End If
    End Function
    ''' <summary>
    ''' 将指定值与此映射中的指定键相关联。如果映射以前包含键的映射，则替换旧值。
    ''' </summary>
    ''' <param name="name">与指定值关联的键</param>
    ''' <param name="value">要与指定键关联的值</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function put(ByVal name As String, ByVal value As Double) As JSONObject
        If checkName(name) Then
            If nameValuePairs.ContainsKey(name) Then
                nameValuePairs.Item(name) = value
                ' Me.Item(name) = value
            Else
                nameValuePairs.Add(name, value)
                'Me.Add(name, value)
            End If
            Return Me
        Else
            Return Me
        End If
    End Function
    ''' <summary>
    ''' 将指定值与此映射中的指定键相关联。如果映射以前包含键的映射，则替换旧值。
    ''' </summary>
    ''' <param name="name">与指定值关联的键</param>
    ''' <param name="value">要与指定键关联的值</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function put(ByVal name As String, ByVal value As Integer) As JSONObject
        If checkName(name) Then
            If nameValuePairs.ContainsKey(name) Then
                nameValuePairs.Item(name) = value
                'Me.Item(name) = value
            Else
                nameValuePairs.Add(name, value)
                'Me.Add(name, value)
            End If
            Return Me
        Else
            Return Me
        End If
    End Function
    ''' <summary>
    ''' 将指定值与此映射中的指定键相关联。如果映射以前包含键的映射，则替换旧值。
    ''' </summary>
    ''' <param name="name">与指定值关联的键</param>
    ''' <param name="value">要与指定键关联的值</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function put(ByVal name As String, ByVal value As UInteger) As JSONObject
        If checkName(name) Then
            If nameValuePairs.ContainsKey(name) Then
                nameValuePairs.Item(name) = value
                'Me.Item(name) = value
            Else
                nameValuePairs.Add(name, value)
                ' Me.Add(name, value)
            End If
            Return Me
        Else
            Return Me
        End If
    End Function
    ''' <summary>
    ''' 将指定值与此映射中的指定键相关联。如果映射以前包含键的映射，则替换旧值。
    ''' </summary>
    ''' <param name="name">与指定值关联的键</param>
    ''' <param name="value">要与指定键关联的值</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function put(ByVal name As String, ByVal value As Long) As JSONObject
        If checkName(name) Then
            If nameValuePairs.ContainsKey(name) Then
                nameValuePairs.Item(name) = value
                'Me.Item(name).Values(= value
            Else
                nameValuePairs.Add(name, value)
                ' Me.Add(name, value)
            End If
            Return Me
        Else
            Return Me
        End If
    End Function
    ''' <summary>
    ''' 将指定值与此映射中的指定键相关联。如果映射以前包含键的映射，则替换旧值。
    ''' </summary>
    ''' <param name="name">与指定值关联的键</param>
    ''' <param name="value">要与指定键关联的值</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function put(ByVal name As String, ByVal value As ULong) As JSONObject
        If checkName(name) Then
            If nameValuePairs.ContainsKey(name) Then
                nameValuePairs.Item(name) = value
                ' Me.Item(name) = value
            Else
                nameValuePairs.Add(name, value)
                'Me.Add(name, value)
            End If
            Return Me
        Else
            Return Me
        End If
    End Function
    ''' <summary>
    ''' 将指定值与此映射中的指定键相关联。如果映射以前包含键的映射，则替换旧值。
    ''' </summary>
    ''' <param name="name">与指定值关联的键</param>
    ''' <param name="value">要与指定键关联的值</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function put(ByVal name As String, ByVal value As Short) As JSONObject
        If checkName(name) Then
            If nameValuePairs.ContainsKey(name) Then
                nameValuePairs.Item(name) = value
                'Me.Item(name) = value
            Else
                nameValuePairs.Add(name, value)
                'Me.Add(name, value)
            End If
            Return Me
        Else
            Return Me
        End If
    End Function
    ''' <summary>
    ''' 将指定值与此映射中的指定键相关联。如果映射以前包含键的映射，则替换旧值。
    ''' </summary>
    ''' <param name="name">与指定值关联的键</param>
    ''' <param name="value">要与指定键关联的值</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function put(ByVal name As String, ByVal value As UShort) As JSONObject
        If checkName(name) Then
            If nameValuePairs.ContainsKey(name) Then
                nameValuePairs.Item(name) = value
                'Me.Item(name) = value
            Else
                nameValuePairs.Add(name, value)
                'Me.Add(name, value)
            End If
            Return Me
        Else
            Return Me
        End If
    End Function
    ''' <summary>
    ''' 将指定值与此映射中的指定键相关联。如果映射以前包含键的映射，则替换旧值。
    ''' </summary>
    ''' <param name="name">与指定值关联的键</param>
    ''' <param name="value">要与指定键关联的值</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function put(ByVal name As String, ByVal value As Single) As JSONObject
        If checkName(name) Then
            If nameValuePairs.ContainsKey(name) Then
                nameValuePairs.Item(name) = value
                'Me.Item(name) = value
            Else
                nameValuePairs.Add(name, value)
                'Me.Add(name, value)
            End If
            Return Me
        Else
            Return Me
        End If
    End Function
    ''' <summary>
    ''' 将指定值与此映射中的指定键相关联。如果映射以前包含键的映射，则替换旧值。
    ''' </summary>
    ''' <param name="name">与指定值关联的键</param>
    ''' <param name="value">要与指定键关联的值</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function put(ByVal name As String, ByVal value As Object) As JSONObject
        If value Is Nothing Then
            ' nameValuePairs.Remove(name)
            Return Me.Remove(name)
            'Return Me
        End If
        If checkName(name) Then
            If nameValuePairs.ContainsKey(name) Then
                nameValuePairs.Item(name) = value
                ' Me.Item(name) = value
            Else
                nameValuePairs.Add(name, value)
                'Me.Add(name, value)
            End If
            Return Me
        Else
            Return Me
        End If
    End Function
    ''' <summary>
    ''' 当两个参数都为非null时，等效于<code> put（name，value）</code>；否则不执行任何操作。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function putOpt(ByVal name As String, ByVal value As Object) As JSONObject
        If Microsoft.VisualBasic.IsNothing(name) Or Microsoft.VisualBasic.IsNothing(value) Then
            Return Me
        Else
            If name.Length = 0 Then
                Return Me
            End If
        End If
        Return put(name, value)
    End Function
    ''' <summary>
    ''' 将<code>value</code>追加到已映射到<code>name</code>的数组。
    ''' 如果此对象没有<code>name</code>的映射，则会插入一个新映射。
    ''' 如果映射存在，但其值不是数组，则按顺序将现有值和新值插入一个新数组，该数组本身映射到<code>name</code>。
    ''' 总的来说，这允许一次向一个映射添加一个值。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Accumulate(ByVal name As String, ByVal value As Object) As JSONObject
        Dim current As Object = nameValuePairs.Item(checkName(name))
        If Microsoft.VisualBasic.IsNothing(current) Then
            Return put(name, value)
        End If
        If current.GetType.Equals(GetType(JSONArray)) Then
            Dim array As JSONArray = current
            array.CheckedPut(value)
        Else
            Dim array As JSONArray = New JSONArray()
            array.CheckedPut(current)
            array.CheckedPut(value)
            nameValuePairs.Add(name, array)
        End If
        Return Me
    End Function
    ''' <summary>
    ''' 将值附加到映射到<code>name</code>的数组。如果不存在映射，<code>name</code>的新<code>JSONArray</code>映射将被插入。
    ''' 如果<code>name</code>的现有映射不是<code>JSONArray</code>，则将抛出<code>Exception</code> 。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Append(ByVal name As String, ByVal value As Object) As JSONObject
        Dim current As Object = nameValuePairs.Item(checkName(name))
        Dim array As JSONArray
        If current Is Nothing Then
            Dim newArray As JSONArray = New JSONArray()
            nameValuePairs.Add(name, newArray)
            array = newArray
        ElseIf current.GetType.Equals(GetType(JSONArray)) Then
            array = current
        Else
            Throw New Exception("Key " + name + " is not a JSONArray")
        End If
        array.CheckedPut(value)
        Return Me
    End Function
    ''' <summary>
    ''' 如果存在，则移除命名映射；否则不执行任何操作。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Remove(ByVal name As String) As Object
        Dim val As Object = nameValuePairs.Item(name)
        nameValuePairs.Remove(name)
        Return val
    End Function
    ''' <summary>
    ''' 如果此对象没有{@code name}的映射或其值为{@link#NULL}的映射，则返回true。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsNothing(ByVal name As String) As Boolean
        Dim value As Object = nameValuePairs(name)
        Return IIf(Microsoft.VisualBasic.IsNothing(value), True, False)
    End Function
    ''' <summary>
    ''' 如果此对象具有{@code name}的映射，则返回true。映射可能是{@link#NULL}。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function has(ByVal name As String) As Boolean
        Return nameValuePairs.ContainsKey(name)
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值，如果不存在这样的映射，则抛出。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getItem(name As String) As Object
        Dim result As Object = Nothing
        If nameValuePairs.Keys.Equals(name) Then
            result = nameValuePairs.Item(name)
        End If
        If result Is Nothing Then
            Throw New Exception("No value for " + name)
        End If
        Return result
    End Function
    ' Public Shared Function numberToString()
    ''' <summary>
    ''' 返回由{@code name}映射的值，如果不存在此类映射，则返回nothing。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function opt(name As String) As Object
        If nameValuePairs.ContainsKey(name) Then
            Return nameValuePairs.Item(name)
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是布尔值，或者可以强制为布尔值，或者抛出其他值）。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getBoolean(ByVal name As String) As Boolean
        Dim val As Object = getItem(name)
        Dim result As Boolean = JSON.toBoolean(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Throw JSON.typeMismatch(name, val, "boolean")
        End If
        Return result
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是布尔值或可以强制为布尔值），否则返回{@code fallback}。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="defaultVal"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function optBoolean(ByVal name As String, Optional ByVal defaultVal As Boolean = False) As Boolean
        Dim val As Object = opt(name)
        Dim result As Boolean = JSON.toBoolean(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Return defaultVal
        Else
            Return val
        End If
    End Function

    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是Byte值，或者可以强制为Byte值，或者抛出其他值）。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getByte(ByVal name As String) As Byte
        Dim val As Object = getItem(name)
        Dim result As Byte = JSON.toByte(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Throw JSON.typeMismatch(name, val, "Byte")
        End If
        Return result
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是布尔值或可以强制为Byte值），否则返回{@code defaultVal}。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="defaultVal"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function optByte(ByVal name As String, Optional ByVal defaultVal As Byte = 0) As Byte
        Dim val As Object = opt(name)
        Dim result As Byte = JSON.toByte(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Return defaultVal
        Else
            Return val
        End If
    End Function

    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是SByte值，或者可以强制为SByte值，或者抛出其他值）。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getSByte(ByVal name As String) As SByte
        Dim val As Object = getItem(name)
        Dim result As SByte = JSON.toSByte(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Throw JSON.typeMismatch(name, val, "SByte")
        End If
        Return result
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是布尔值或可以强制为SByte值），否则返回{@code defaultVal}。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="defaultVal"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function optSByte(ByVal name As String, Optional ByVal defaultVal As SByte = 0) As SByte
        Dim val As Object = opt(name)
        Dim result As SByte = JSON.toSByte(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Return defaultVal
        Else
            Return val
        End If
    End Function

    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是Short值，或者可以强制为Short值，或者抛出其他值）。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getShort(ByVal name As String) As Short
        Dim val As Object = getItem(name)
        Dim result As Short = JSON.toShort(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Throw JSON.typeMismatch(name, val, "Short")
        End If
        Return result
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是布尔值或可以强制为Short值），否则返回{@code defaultVal}。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="defaultVal"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function optShort(ByVal name As String, Optional ByVal defaultVal As Short = 0) As Short
        Dim val As Object = opt(name)
        Dim result As Short = JSON.toShort(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Return defaultVal
        Else
            Return val
        End If
    End Function

    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是UShort值，或者可以强制为UShort值，或者抛出其他值）。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getUShort(ByVal name As String) As UShort
        Dim val As Object = getItem(name)
        Dim result As UShort = JSON.toUShort(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Throw JSON.typeMismatch(name, val, "UShort")
        End If
        Return result
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是布尔值或可以强制为UShort值），否则返回{@code defaultVal}。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="defaultVal"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function optUShort(ByVal name As String, Optional ByVal defaultVal As UShort = 0) As UShort
        Dim val As Object = opt(name)
        Dim result As UShort = JSON.toUShort(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Return defaultVal
        Else
            Return val
        End If
    End Function

    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是Char值，或者可以强制为Char值，或者抛出其他值）。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getChar(ByVal name As String) As Char
        Dim val As Object = getItem(name)
        Dim result As Char = JSON.toChar(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Throw JSON.typeMismatch(name, val, "Char")
        End If
        Return result
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是布尔值或可以强制为Char值），否则返回{@code defaultVal}。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="defaultVal"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function optChar(ByVal name As String, Optional ByVal defaultVal As Char = Chr(0)) As Char
        Dim val As Object = opt(name)
        Dim result As Char = JSON.toChar(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Return defaultVal
        Else
            Return val
        End If
    End Function

    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是Integer值，或者可以强制为Integer值，或者抛出其他值）。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getInteger(ByVal name As String) As Integer
        Dim val As Object = getItem(name)
        Dim result As Integer = JSON.toInteger(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Throw JSON.typeMismatch(name, val, "UShort")
        End If
        Return result
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是布尔值或可以强制为Integer值），否则返回{@code defaultVal}。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="defaultVal"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function optInteger(ByVal name As String, Optional ByVal defaultVal As Integer = 0) As Integer
        Dim val As Object = opt(name)
        Dim result As Integer = JSON.toInteger(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Return defaultVal
        Else
            Return val
        End If
    End Function

    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是UInteger值，或者可以强制为UInteger值，或者抛出其他值）。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getUInteger(ByVal name As String) As UInteger
        Dim val As Object = getItem(name)
        Dim result As UInteger = JSON.toUInteger(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Throw JSON.typeMismatch(name, val, "UInteger")
        End If
        Return result
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是布尔值或可以强制为UInteger值），否则返回{@code defaultVal}。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="defaultVal"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function optUInteger(ByVal name As String, Optional ByVal defaultVal As UInteger = 0) As UInteger
        Dim val As Object = opt(name)
        Dim result As UInteger = JSON.toUInteger(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Return defaultVal
        Else
            Return val
        End If
    End Function

    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是Long值，或者可以强制为Long值，或者抛出其他值）。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getLong(ByVal name As String) As Long
        Dim val As Object = getItem(name)
        Dim result As Long = JSON.toLong(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Throw JSON.typeMismatch(name, val, "Long")
        End If
        Return result
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是布尔值或可以强制为Long值），否则返回{@code defaultVal}。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="defaultVal"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function optLong(ByVal name As String, Optional ByVal defaultVal As Long = 0) As Long
        Dim val As Object = opt(name)
        Dim result As Long = JSON.toLong(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Return defaultVal
        Else
            Return val
        End If
    End Function

    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是ULong值，或者可以强制为ULong值，或者抛出其他值）。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getULong(ByVal name As String) As ULong
        Dim val As Object = getItem(name)
        Dim result As ULong = JSON.toULong(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Throw JSON.typeMismatch(name, val, "ULong")
        End If
        Return result
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是布尔值或可以强制为ULong值），否则返回{@code defaultVal}。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="defaultVal"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function optULong(ByVal name As String, Optional ByVal defaultVal As ULong = 0) As ULong
        Dim val As Object = opt(name)
        Dim result As ULong = JSON.toULong(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Return defaultVal
        Else
            Return val
        End If
    End Function

    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是Single值，或者可以强制为Single值，或者抛出其他值）。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getSingle(ByVal name As String) As Single
        Dim val As Object = getItem(name)
        Dim result As Single = JSON.toSingle(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Throw JSON.typeMismatch(name, val, "Single")
        End If
        Return result
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是布尔值或可以强制为Single值），否则返回{@code defaultVal}。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="defaultVal"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function optSingle(ByVal name As String, Optional ByVal defaultVal As Single = 0) As Single
        Dim val As Object = opt(name)
        Dim result As Single = JSON.toSingle(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Return defaultVal
        Else
            Return val
        End If
    End Function

    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是Double值，或者可以强制为Double值，或者抛出其他值）。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getDouble(ByVal name As String) As Double
        Dim val As Object = getItem(name)
        Dim result As Double = JSON.toDouble(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Throw JSON.typeMismatch(name, val, "Double")
        End If
        Return result
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是布尔值或可以强制为Double值），否则返回{@code defaultVal}。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="defaultVal"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function optDouble(ByVal name As String, Optional ByVal defaultVal As Double = 0) As Double
        Dim val As Object = opt(name)
        Dim result As Double = JSON.toDouble(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Return defaultVal
        Else
            Return val
        End If
    End Function

    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是String值，或者可以强制为String值，或者抛出其他值）。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getString(ByVal name As String) As String
        Dim val As Object = getItem(name)
        Dim result As String = JSON.ToString(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Throw JSON.typeMismatch(name, val, "String")
        End If
        Return result
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是布尔值或可以强制为String值），否则返回{@code defaultVal}。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <param name="defaultVal"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function optString(ByVal name As String, Optional ByVal defaultVal As String = Nothing) As String
        Dim val As Object = opt(name)
        Dim result As String = JSON.ToString(val)
        If Microsoft.VisualBasic.IsNothing(result) Then
            Return defaultVal
        Else
            Return val
        End If
    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果它存在并且是{@code JSONArray}），否则抛出。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getJSONArray(ByVal name As String) As JSONArray
        Dim val As Object = getItem(name)
        If val.GetType.Equals(GetType(JSONArray)) Then
            Return val
        ElseIf IsArray(val) Or val.GetType.Equals(GetType(ArrayList)) Or val.GetType.Equals(GetType(IList(Of Object))) Or val.GetType.Equals(GetType(List(Of Object))) Then
            Return New JSONArray(val)
        Else
            Throw JSON.typeMismatch(name, val, "JSONArray")
        End If

    End Function
    ''' <summary>
    ''' 返回由{@code name}映射的值（如果该值存在并且是{@code JSONArray}），否则返回nothing。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function optJSONArray(ByVal name As String) As JSONArray
        Dim val As Object = opt(name)
        If val IsNot Nothing Then
            If val.GetType.Equals(GetType(JSONArray)) Then
                Return val
            ElseIf IsArray(val) Or val.GetType.Equals(GetType(ArrayList)) Or val.GetType.Equals(GetType(IList(Of Object))) Or val.GetType.Equals(GetType(List(Of Object))) Then
                Return New JSONArray(val)
            Else
                Return Nothing
            End If
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 返回由{@code name}处的值（如果该值存在并且是或者强制转换为<code>JSONObject</code>），否则抛出。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getJSONObject(ByVal name As String) As JSONObject
        Dim val As Object = getItem(name)
        If val.GetType.Equals(GetType(JSONObject)) Then
            Return val
        ElseIf val.GetType.Equals(GetType(Dictionary(Of String, Object))) Then
            Dim d As Dictionary(Of String, Object) = val
            Return New JSONObject(d)
        ElseIf val.GetType.Equals(GetType(SortedDictionary(Of String, Object))) Then
            Dim sd As SortedDictionary(Of String, Object) = val
            Dim d As Dictionary(Of String, Object) = New Dictionary(Of String, Object)
            For Each kvp As KeyValuePair(Of String, Object) In sd   '遍历元素
                d.Add(kvp.Key, kvp.Value)
            Next
            Return New JSONObject(d)
        ElseIf val.GetType.Equals(GetType(String)) Then
            Return New JSONObject(CStr(val))
        Else
            Throw JSON.typeMismatch(name, val, "JSONObject")
        End If
    End Function

    ''' <summary>
    ''' 返回<code>name</code>处的值（如果该值存在并且是或可以强制为<code>JSONObject</code>）。否则返回Nothing。
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function optJSONObject(ByVal name As String) As JSONObject
        Dim val As Object = opt(name)
        Try
            If val.GetType.Equals(GetType(JSONObject)) Then
                Return val
            ElseIf val.GetType.Equals(GetType(Dictionary(Of String, Object))) Then
                Dim d As Dictionary(Of String, Object) = val
                Return New JSONObject(d)
            ElseIf val.GetType.Equals(GetType(SortedDictionary(Of String, Object))) Then
                Dim sd As SortedDictionary(Of String, Object) = val
                Dim d As Dictionary(Of String, Object) = New Dictionary(Of String, Object)
                For Each kvp As KeyValuePair(Of String, Object) In sd   '遍历元素
                    d.Add(kvp.Key, kvp.Value)
                Next
                Return New JSONObject(d)
            ElseIf val.GetType.Equals(GetType(String)) Then
                Return New JSONObject(CStr(val))
            Else
                Return Nothing
            End If
        Catch ex As Exception
            Return Nothing
        End Try
    End Function
    ''' <summary>
    ''' 返回值与{@code names}对应的数组。对于未映射的名称，数组包含null。如果{@code names}为null或空，则此方法返回null。
    ''' </summary>
    ''' <param name="names"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function toJSONArray(ByVal names As JSONArray) As JSONArray
        Dim result As JSONArray = New JSONArray()
        If names Is Nothing Then
            Return Nothing
        End If
        If names.Count = 0 Then
            Return Nothing
        End If
        For i As Integer = 0 To names.Count - 1
            Dim name As String = JSON.ToString(names.Opt(i))
            result.Put(opt(name))
        Next
        Return result
    End Function
    ''' <summary>
    ''' 将此对象编码为压缩JSON字符串，例如：
    ''' {"query":"Pizza","locations":[94043,90210]}
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overloads Function toString() As String
        Try
            Dim stringer As JSONStringer = New JSONStringer()
            writeTo(stringer)
            Return stringer.toString()
        Catch ex As Exception
            Return Nothing
        End Try
    End Function
    ''' <summary>
    ''' 将此数组编码为用于调试的可读JSON字符串，例如：[94043, 90210]
    ''' </summary>
    ''' <param name="indentSpaces">嵌套的每个级别缩进的空格数。</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overloads Function toString(ByVal indentSpaces As Integer) As String
        Dim stringer As JSONStringer = New JSONStringer(indentSpaces)
        writeTo(stringer)
        Return stringer.toString()
    End Function
    ''' <summary>
    ''' 检测键名是否有效
    ''' </summary>
    ''' <param name="name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Friend Function checkName(ByVal name As String) As Boolean
        Dim isNotNull As Boolean = False
        If Not Microsoft.VisualBasic.IsNothing(name) Then
            If name.Length > 0 Then
                isNotNull = True
            End If
        End If
        Return isNotNull
    End Function
    Friend Sub writeTo(stringer As JSONStringer)
        stringer.startObject()
        For Each entry In nameValuePairs
            stringer.key(entry.Key).value(entry.Value)
        Next
        stringer.endObject()
    End Sub
    ''' <summary>
    ''' 将数字编码为JSON字符串。
    ''' </summary>
    ''' <param name="number"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function numberToString(ByVal number As Object) As String
        If number Is Nothing Then
            Throw New Exception("Number must be non-null")
        End If
        Dim doubleValue As Double = CDbl(number)
        If number.Equals(NEGATIVE_ZERO) Then
            Return "-0"
        End If
        Dim longValue As Long = CLng(number)
        If doubleValue = CDbl(longValue) Then
            Return longValue.ToString
        End If
        Return number.ToString()
    End Function
    ''' <summary>
    ''' 将{@code data}编码为JSON字符串。这将应用引号和任何必要的字符转义。
    ''' </summary>
    ''' <param name="data">要编码的字符串。Nothing将被解释为空</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function quote(ByVal data As String) As String
        If data Is Nothing Then
            Return """"""   '返回两个双引号
        End If
        Try
            Dim stringer As JSONStringer = New JSONStringer()
            stringer.open(JSONStringer.Scope.NULL, "")
            stringer.value(data)
            stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "")
            Return stringer.toString()
        Catch ex As Exception
            Throw New Exception(ex.Message)
        End Try
    End Function
    ''' <summary>
    ''' 如有必要，包装给定对象。
    ''' 如果对象是<code>JSONArray</code>或<code>JSONObject</code>，则不需要包装。
    ''' 如果对象是<code>Array</code>、<code>ArrayList</code>或<code>List(Of Object)</code>，则返回等效的<code>JSONArray</code>。
    ''' 如果对象是原始包装类型或<code>String</code>，则返回对象。
    ''' </summary>
    ''' <param name="o"></param>
    ''' <returns>如果包装失败，则返回Nothing。</returns>
    ''' <remarks></remarks>
    Public Shared Function wrap(ByVal o As Object) As Object
        If o Is Nothing Then
            Return "null"
        End If
        If o.GetType.Equals(GetType(JSONArray)) Or o.GetType.Equals(GetType(JSONObject)) Then
            Return o
        End If
        Try
            If o.GetType.Equals(GetType(ArrayList)) Then
                Dim aList As ArrayList = o
                Return New JSONArray(aList)
            ElseIf o.GetType.Equals(GetType(Array)) Then
                Dim a As Array = o
                Return New JSONArray(a)
            ElseIf o.GetType.Equals(GetType(List(Of Object))) Then
                Dim l As List(Of Object) = o
                Return New JSONArray(l)
            ElseIf o.GetType.Equals(GetType(HashSet(Of Object))) Then
                Dim l As HashSet(Of Object) = o
                Return New JSONArray(l)
            ElseIf o.GetType.Equals(GetType(SortedSet(Of Object))) Then
                Dim l As SortedSet(Of Object) = o
                Return New JSONArray(l)
            ElseIf o.GetType.Equals(GetType(Boolean)) Or o.GetType.Equals(GetType(Byte)) Or _
                o.GetType.Equals(GetType(SByte)) Or o.GetType.Equals(GetType(Short)) Or _
                o.GetType.Equals(GetType(UShort)) Or o.GetType.Equals(GetType(Integer)) Or _
                o.GetType.Equals(GetType(UInteger)) Or o.GetType.Equals(GetType(Long)) Or _
                o.GetType.Equals(GetType(ULong)) Or o.GetType.Equals(GetType(Single)) Or _
                o.GetType.Equals(GetType(Double)) Or o.GetType.Equals(GetType(Char)) Or _
                 o.GetType.Equals(GetType(String)) Then
                Return o
            End If
        Catch ex As Exception
        End Try
        Return Nothing
    End Function
    ''''''''''''''''''''''''''''''''''''接口实现属性及方法''''''''''''''''''''''''''''''''''''''''
    '''''''''''''''属性'''''''''''''''''''
    ''' <summary>
    ''' 返回列表长度
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Count() As Integer
        Get
            Return nameValuePairs.Count
        End Get
    End Property
    ''' <summary>
    ''' 返回包含此对象中的字符串名称的数组。
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property NamesAt() As Dictionary(Of String, Object).KeyCollection
        Get
            Return nameValuePairs.Keys()
        End Get
    End Property
    ''' <summary>
    ''' 返回包含此对象中的字符串名称的数组。如果此对象不包含映射，则此方法返回Nothing。
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Names() As JSONArray
        Get
            If nameValuePairs Is Nothing Then
                Return Nothing
            Else
                Dim arr As Array = nameValuePairs.Keys().ToArray
                Return New JSONArray(arr)
            End If
        End Get
    End Property
    Public ReadOnly Property IsReadOnly As Boolean
        Get
            Return False
        End Get
    End Property
    Public ReadOnly Property Values As ICollection(Of Object)
        Get
            Return nameValuePairs.Values
        End Get
    End Property
    Public Function Contains(ByVal k As KeyValuePair(Of String, Object)) As Boolean
        Return nameValuePairs.Contains(k)
    End Function
    Public Sub Clear()
        nameValuePairs.Clear()
    End Sub
    Public Sub CopyTo(array() As KeyValuePair(Of String, Object), arrayIndex As Integer)
        If array Is Nothing Then
            Throw New ArgumentNullException("The array cannot be null.")
        ElseIf arrayIndex < 0 Then
            Throw New ArgumentOutOfRangeException("The starting array index cannot be negative.")
        ElseIf Count > array.Length - arrayIndex + 1 Then
            Throw New ArgumentException("The destination array has fewer elements than the collection.")
        End If

        Dim keyList As List(Of KeyValuePair(Of String, Object)) = nameValuePairs.ToList
        For i As Integer = 0 To nameValuePairs.Count - 1
            ' Dim key As String = nameValuePairs.
            array(i + arrayIndex) = keyList.Item(i)
        Next
    End Sub
End Class
